# 问题1：标准化后未正确恢复参数
# 问题2：未标准化的学习率设置不当
# 问题3：标准化后的偏置项处理

# 解决
import numpy as np
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt

# 生成数据
np.random.seed(42)
X1 = 5 * np.random.rand(100, 1)
X2 = 1000 * np.random.rand(100, 1)
y = 5 + 4 * X1 + 3 * X2 + np.random.rand(100, 1)

# 未标准化的设计矩阵
X_c = np.c_[np.ones((100, 1)), X1, X2]



# 未标准化的梯度下降
theta = np.random.rand(3, 1)
lr = 1e-6
for _ in range(10000):
    grad = X_c.T.dot(X_c.dot(theta) - y) / len(X_c)
    theta -= lr * grad
print("未标准化参数:", theta)

# 标准化的梯度下降
# 标准化（仅对特征列）
scaler = StandardScaler()
X1_X2 = np.c_[X1, X2]
X_scaled = scaler.fit_transform(X1_X2)
X_scaled_c = np.c_[np.ones((100, 1)), X_scaled]
theta_scaled = np.random.rand(3, 1)
lr = 0.1
for _ in range(100):
    grad = X_scaled_c.T.dot(X_scaled_c.dot(theta_scaled) - y) / len(X_scaled_c)
    theta_scaled -= lr * grad
print("标准化参数（标准化尺度）:", theta_scaled)

# 将标准化参数转换回原始尺度
# 参数逆变换
theta_scaled_original = np.zeros_like(theta_scaled)
scale_reshaped = scaler.scale_.reshape(2, 1)  # 转为 (2, 1)
mean_reshaped = scaler.mean_.reshape(2, 1)    # 转为 (2, 1)

theta_scaled_original[0] = theta_scaled[0] - np.sum(theta_scaled[1:] * mean_reshaped / scale_reshaped)
theta_scaled_original[1:] = theta_scaled[1:] / scale_reshaped  # 形状匹配

print("标准化参数（原始尺度）:", theta_scaled_original)